const Rize = require('rize');
const rize = new Rize({headless: false});
const colors = require('colors');

colors.setTheme({
    silly: 'rainbow',
    input: 'grey',
    verbose: 'cyan',
    prompt: 'red',
    info: 'green',
    data: 'blue',
    help: 'cyan',
    warn: 'yellow',
    debug: 'magenta',
    error: 'red'
});

class Crawler {
    constructor({url}) {
        this.url = url;
        this.colorClassification = null;
        this.init()
    }

    async init() {
        await rize.goto(this.url, {waitUntil: 'networkidle2'})
    }

    sleep(item) {
        return new Promise(resolve => {
            setTimeout(() => {
                resolve(true)
            }, item)
        })
    }

    async theData(fn, fnc) {
        let dataUrl = '';
        return new Promise(async (resolve) => {
            await rize.execute(async (browser, page) => {
                let data = await fn(page);
                // console.log(data)
                if (data) {
                    dataUrl = data
                }
                resolve(data)
            })
        })
    }

    async evaluateWith(fnc) {

        const byExpr = await rize.evaluateWithReturn(fnc);
        // console.log(byExpr)
        return byExpr
    }

    async PageDown({fn, fnc, page = 10} = {}) {
        let i = 0;
        let self = this;
        let itemr = null;
        await self.sleep(500)
        return new Promise(async (resolve) => {
            (async function item() {
                if (i > page) {

                    if (fn) {
                        resolve(self.theData(fn));
                    } else {
                        resolve(self.evaluateWith(fnc))
                    }
                    console.log('翻页完成')
                    return;
                }

                itemr = setTimeout(async () => {

                    i++
                    await rize.keyDown('PageDown');
                    item();
                }, 250)
            })()
        })
    }

    async newPage({name, obj, url} = {}) {
        await rize.newPage(name, obj);
        await rize.goto(url, {waitUntil: 'networkidle2'});
        await this.sleep(1000);
        return Promise.resolve(true);
    }

    async closePage({name} = {}) {
        await rize.closePage(name)
        return await Promise.resolve(true)
    }

    async switchPage({name}) {
        await rize.switchPage(name)
        return await Promise.resolve(true)
    }

    click({
              versionsOrModel,
              colorClassification,
              fn,
              fnc,
              page,
              vmmetatit,
              specificationParameter,
              FREQUENTLYASKEDQUESTIONS,
              specification_fn,
              FAQ_FN,
              written_message_fn,
              biaoqian_fn
          } = {}) {
        let i = 0;
        let self = this;
        let arrData = [];
        let arr = [];
        let contentData = null;
        let iSonce = true;
        let specification_arameter_data = null;
        let FAQ_DATA = null;
        let written_message = null;
        let isColor = true;
        return new Promise(resolve => {
            (async function recursion() {

                if (!versionsOrModel[i] && i>=1) {
                    arr.push(arrData)
                    resolve(arr)
                    return false;
                }

                if (versionsOrModel[i]) {
                    console.log(' i === 1     的时候开始执行 开始执行')
                    await rize.click(versionsOrModel[i]);
                    await self.sleep(1500);
                    self.colorClassification = await self.evaluateWith(biaoqian_fn)
                    console.log('开始执行',self.colorClassification)

                    if(self.colorClassification.length){
                        console.log('-------->    颜色分类单击的类型开始执行'.green)
                        console.log(`位置 -------> ${i} `,self.colorClassification);
                        for (let j = 0; j < self.colorClassification.length; j++) {
                            await self.sleep(1000);
                            await rize.click(self.colorClassification[j]);
                            let dataArr = await self.evaluateWith(vmmetatit);
                            let name = `color_classification_img_${i}_${j}`;
                            let obj = {};
                            obj[name] = dataArr;
                            arrData.push(obj);
                            console.log('-------->    开始等待500毫秒')
                            await self.sleep(500);
                        }
                    }
                } else if (versionsOrModel.length ===0) {
                    console.log('versionsOrModel.length === 0 开始执行');

                    if (colorClassification.length && isColor) {
                        console.log('-------->    颜色分类开始执行开始执行'.green)
                        for (let j = 0; j < colorClassification.length; j++) {
                            await self.sleep(1000);
                            await rize.click(colorClassification[j]);
                            let dataArr = await self.evaluateWith(vmmetatit);

                            let name = `color_classification_img_${i}_${j}`;
                            let obj = {};
                            obj[name] = dataArr;
                            arrData.push(obj);
                            console.log('-------->    开始等待500毫秒')
                            await self.sleep(500);
                        }
                        isColor = false;
                    }


                }
                    console.log('-------->    开始等待300毫秒'.yellow)


                await self.sleep(500)



                console.log('*****************  开始执行主体内容 ****************')

                console.log('-------->    开始等待500毫秒'.yellow)
                await self.sleep(500);


                if (iSonce) {
                    console.log('-------->    300毫秒   开始获取商品详情文字信息'.red);
                    await self.sleep(300);
                    written_message = await self.evaluateWith(written_message_fn)
                    arrData.push({written_message})
                    console.log('------>   商品详情文字信息获取完毕'.red)
                }
                // await self.sleep(100000)


                if (versionsOrModel[i] || iSonce) {
                    contentData = await self.PageDown({fn, fnc, page});
                    let name = `commodity_detail_mg_${i}`;
                    let obj = {};
                    obj[name] = contentData;
                    arrData.push(obj);

                    if (specificationParameter[i]) {
                        console.log('----->  300毫秒后获取数据规格参数'.green)
                        await self.sleep(300)
                        specification_arameter_data = await self.evaluateWith(specification_fn);
                        arrData.push({specification_arameter_data});

                        console.log('------>   据规格参数获取完毕'.red)
                    }


                    if (FREQUENTLYASKEDQUESTIONS[i]) {
                        console.log('------>   300毫秒后又开始获取常见文件'.green)
                        await self.sleep(300)
                        FAQ_DATA = await self.evaluateWith(FAQ_FN)
                        arrData.push({FAQ_DATA})
                        console.log('------>  常见问题获取完毕'.red)
                    }
                    iSonce = false;
                }



                await self.sleep(200);
                if (contentData) {
                    i++;
                    console.log(`------>     第${i}次     200毫秒开始执行递归`.red);
                    await self.sleep(200)
                    recursion()
                }
            })()

        })
    }
}


function recursion_1({i, len, array, time = 1500, fn, fnc} = {}) {
    return new Promise(resolve => {
        (function recursion(arr) {
            if (i >= len) {
                resolve(true);
                return;
            }
            ;

            timer = setTimeout(async () => {
                fn && await fn(arr[i], i);
                fnc && await fnc();
                i++;
                recursion(arr);
            }, time)

        })(array)
    })
}


exports.Craw = Crawler;
exports.rize = rize;
exports.recursion_1 = recursion_1;


